package me.yidasanqian.crowdfunding.config;

import io.jsonwebtoken.lang.Collections;
import me.yidasanqian.crowdfunding.domain.Permission;
import me.yidasanqian.crowdfunding.domain.Role;
import me.yidasanqian.crowdfunding.domain.User;
import me.yidasanqian.crowdfunding.domain.UserAuthc;
import me.yidasanqian.crowdfunding.service.IUserAuthcService;
import me.yidasanqian.crowdfunding.service.IUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Linyu Chen
 */
@Configuration
public class MyShiroRealm extends AuthorizingRealm {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Resource
    private IUserAuthcService userAuthcService;

    @Resource
    private IUserService userService;

    // 登录认证实现
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("doGetAuthenticationInfo 登录认证");
        // 获取用户的输入的账号.
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        log.info("doGetAuthenticationInfo username <==" + username);
        UserAuthc userAuthc = userAuthcService.getUserAuthc(username);
        if (userAuthc != null) {
            User user = userService.getUserByAuthcId(userAuthc.getId());
            String credentialSalt = username + userAuthc.getSalt();
            if (user != null) {
                return new SimpleAuthenticationInfo(
                        username,
                        userAuthc.getCredential(),
                        ByteSource.Util.bytes(credentialSalt),
                        getName()
                );
            }
        }

        return null;
    }

    // 链接权限的实现
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("doGetAuthenticationInfo 权限授权");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String username = (String) principalCollection.getPrimaryPrincipal();
        List<Role> roleList = userService.listRolesByUsername(username);

        Set<String> permissionSet = new HashSet<String>();
        Set<String> roleNameSet = new HashSet<String>();

        for (Role role : roleList) {
            List<Permission> permissionList = userService.listPermissionsByRoleId(role.getId());
            if (!Collections.isEmpty(permissionList)) {
                for (Permission permission : permissionList) {
                    if (!StringUtils.isEmpty(permission.getPermission())) {
                        permissionSet.add(permission.getPermission());
                    }
                }
            }
            roleNameSet.add(role.getRole());
        }

        authorizationInfo.addRoles(roleNameSet);
        authorizationInfo.addStringPermissions(permissionSet);
        return authorizationInfo;
    }

    /**
     * 设置认证加密方式
     *
     * @param credentialsMatcher
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");
        matcher.setHashIterations(2);
        super.setCredentialsMatcher(matcher);
    }


}
